// let与块级作用域


//例如if语句和循环语句
// if(true){
//     console.log('这里是块级作用域')
// }
// for(var i = 0 ; i < 10 ; i++){
//     console.log(i,'这里是块级作用域')
// }
// //------------------------------------
// if(true){
//     var a = 123;
// }
// console.log(a); //==>打印出123
// //-------------------------------------
// if(true){
//     let a = 123;
// }
// console.log(a); //==>打印出 a is not defind
// // ---------------------------------------
// for(var i = 0 ; i < 3 ; i++){
//     for(var i = 0 ; i < 3 ; i++){
//        console.log(i)
//    } 
//    console.log('内层结束i=' + i)//当i=3时，不符合外部循环条件，循环停止
// }
//输出结果0 1 2 内层结束i=3
//A，B两个for循环的嵌套，他们声明的变量都是i，双层循环嵌套实际上应该3*3打印9次，但上面就打印了三次，原因是两次循环声明变量用的是var，所以他们的变量i不是不是块级成员，而是全局成员，那内层声明的i就会覆盖掉外层声明的i，那么内层拿到的是3，当i=3时，不符合外部循环条件i<3，循环停止  

// for(let i = 0 ; i < 3 ; i++){
//    for(let i = 0 ; i < 3 ; i++){
//        console.log(i)
//    }
//    console.log('内存循环输出i=' + i)
// }
//输出结果： 0 1 2 内存循环输出i=0 0 1 2 内存循环输出i=1 0 1 2 内存循环输出i=2
//let就不会有这问题，let所声明的变量只会在当前循环的代码块中生效，i只是当前块级作用域的局部变量，不会影响到外层的变量
// --------------------------------------------------
// var elements = [{},{},{}];//每一个空对象都代表一个元素
// for(var i = 0 ; i < elements.length ; i++){
// 	elements[i].onclick=function(){
// 		console.log(i)
// 	}
// }
// elements[0].onclick();//3
// elements[1].onclick();//3
// elements[2].onclick();//3
// //这里打印的i实际上是全局作用域的i，当指向函数的时候实际上循环已经执行过后i已经累加到了3，所以不管你打印那个i最后的结果都是3
// //实际上这也是一个闭包的应用场景，我们通过使用闭包也可以解决这类问题



var elements = [{},{},{}];//每一个空对象都代表一个元素
for(var i = 0 ; i < elements.length ; i++){
	elements[i].onclick = (function(i){
		return function(){
			console.log(i)
		}
	})(i)
}
elements[0].onclick();//0
elements[1].onclick();//1
elements[2].onclick();//2
//闭包通过借助函数作用域来拜托全局作用域的影响
//在块级作用域就不用这么麻烦了，我们把声明计数器的var改成let，使我们的i只能在块级作用域内被访问，这样问题自然就解决了，其实这个内部也是一种闭包的机制，在onclick执行的时候循环已经结束了，这时i已经销毁了，只有执行闭包机制我们才能获得这个i
//---------------------------------------
for(let i = 0 ; i < 3 ; i++){
    let i = 'foo';
}
//输出结果：foo foo foo
let i = 0 ;//外部循环的局部变量
for(i = 0 ; i < 3 ; i++){
    let i = 'foo';//块级作用域内部的局部变量
}
//--------------------------------------
console.log(a);//值为underfined，这里的现象叫变量声明的提升
// var a = 1；
// console.log(a);//报错：在初始化之前不能访问'a'
// let a = 1；